/**
 * Copyright (C)  2011  chen wei hua.
 * Permission is granted to copy, distribute and/or modify this document
 * under the terms of the GNU Free Documentation License, Version 2.0
 * or any later version published by the Free Software Foundation;
 * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
 * A copy of the license is included in the section entitled "GNU Free Documentation License".
 */
package com.javaeye.plan.web;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.javaeye.delivery.dto.OrderCheck;
import com.javaeye.delivery.dto.OrderDetailBatchInfo;
import com.javaeye.delivery.service.ICheckOrderService;
import com.javaeye.plan.dto.MaterialRequisiteForm;
import com.javaeye.plan.dto.MaterialRequisiteFormDetail;
import com.javaeye.plan.service.IBackMaterialRequisiteFormService;
import com.javaeye.store.dto.MaterialsBatchDetail;

public class BackMaterialRequisiteFormAction extends MaterialRequisiteFormAction {
	
	protected static Log log = LogFactory.getLog(BackMaterialRequisiteFormAction.class); 
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -3216585574200112708L;
	
	/**
	 * 
	 */
	private List<Float> qualifiedBackNums;
	
	/**
	 * 
	 */
	private List<Float> unqualifiedBackNums;
	
	private List<Float> inStroeNumbers;
	
	private List<String> inStroeBatchNos;
	
	private OrderCheck checkResult;
	
	private List<OrderCheck> checkResults;
	
	private ICheckOrderService checkService;
	
	/**
	 * Service
	 */
	private IBackMaterialRequisiteFormService backService;

	public void setBackService(IBackMaterialRequisiteFormService backService) {
		this.backService = backService;
	}
	
	public void setCheckService(ICheckOrderService checkService) {
		this.checkService = checkService;
	}
	
	public String removeBackMaterialRequisiteForm() throws Exception {
		backService.removeBackMaterialRequisiteForm(getFormId());
		return SUCCESS;
	}

	public String queryMaterialRequisiteFormCheckResult() throws Exception {
		checkResults = checkService.getCheckResult(getFormId());
		for (OrderCheck c : checkResults) {
			String result = c.getResult();
			if ("合格".equals(result)) {
				result = "同意退料";
			} else {
				result = "不同意退料";
			}
			c.setResult(result);
		}
		return SUCCESS;
	}
	
	public String queryBackMaterialRequisiteFormWaitCheck() throws Exception {
		getCondition().setStatusList(new Integer[] {
				MaterialRequisiteForm.MATERIAL_REQUISITE_FORM_STATUS_CREATE,
				MaterialRequisiteForm.MATERIAL_REQUISITE_FORM_STATUS_CHECKED
		});
		getCondition().setTypeList(new Integer[] {
				MaterialRequisiteForm.FORM_TYPE_QUALIFIED_BACK,
				MaterialRequisiteForm.FORM_TYPE_UNQUALIFIED_BACK
		});
		return queryMaterialRequisiteFormList();
	}
	
	public String queryBackMaterialRequisiteFormInStore() throws Exception {
		getCondition().setTypeList(new Integer[] {
				MaterialRequisiteForm.FORM_TYPE_QUALIFIED_BACK,
				MaterialRequisiteForm.FORM_TYPE_UNQUALIFIED_BACK
		});
		getCondition().setStatus(MaterialRequisiteForm.MATERIAL_REQUISITE_FORM_WAIT_IN_STORE);
		return queryMaterialRequisiteFormList();
	}
	
	public String queryMaterialRequisiteFormForInStore() throws Exception {
		MaterialRequisiteForm mrForm = service.getMaterialRequisiteForm(getFormId());
		setMrForm(mrForm);
		Set<MaterialRequisiteFormDetail> details = mrForm.getFormDetails();
		for (MaterialRequisiteFormDetail detail : details) {
			List<OrderDetailBatchInfo> batchInfos = 
				orderDetailBatchInfoService.getBatchInfo(mrForm.getSourceFormId(), detail.getMaterialId());
			float detailNumber = detail.getNumber();
			List<MaterialsBatchDetail> myBatchInfos = new ArrayList<MaterialsBatchDetail>();
			for (int i = batchInfos.size() - 1; i >= 0; i--) {
				OrderDetailBatchInfo info = batchInfos.get(i);
				float infoNumber = info.getNumber() - info.getBackNumber();
				if (detailNumber > 0) {
					float inStoreNumber = (detailNumber < infoNumber) ? detailNumber : infoNumber;
					detailNumber -= inStoreNumber;
					MaterialsBatchDetail batchInfo = new MaterialsBatchDetail();
					batchInfo.setBatchNo(info.getBatchNo());
					batchInfo.setNumber(infoNumber);
					batchInfo.setInNumber(inStoreNumber);
					myBatchInfos.add(batchInfo);
				}
			}
			detail.setBatchInfos(myBatchInfos);
		}
		return SUCCESS;
	}
	
	public String saveBackMaterialsReceiveCheckResult() throws Exception {
		backService.saveBackMaterialRequisiteCheckResult(checkResult);
		return SUCCESS;
	}
	
	public String saveBackMaterialRequisiteFormInStore() throws Exception {
		String formId = getFormId();
		List<Integer> detailIds = getDetailIds();
		List<Integer> materialIds = getMaterialIds();
		//批次出库信息
		List<OrderDetailBatchInfo> batchInfos = new ArrayList<OrderDetailBatchInfo>();
		for (int i = 0; i < inStroeNumbers.size(); i++) {
			float number = inStroeNumbers.get(i);
			if (number > 0) {
				OrderDetailBatchInfo orderDetailBatchInfo = new OrderDetailBatchInfo();
				orderDetailBatchInfo.setOrderId(formId);
				orderDetailBatchInfo.setOrderDetailId(detailIds.get(i));
				orderDetailBatchInfo.setProductId(materialIds.get(i));
				orderDetailBatchInfo.setBatchNo(inStroeBatchNos.get(i));
				orderDetailBatchInfo.setNumber(number);
				batchInfos.add(orderDetailBatchInfo);
			}
		}
		backService.materialRequisiteFormInStore(formId, batchInfos);
		return SUCCESS;
	}
	
	/**
	 * 保存退料单
	 * @return
	 * @throws Exception
	 */
	public String saveEditBackMaterialRequisiteForm() throws Exception {
		List<Float> materialNums = getMaterialNums();
		MaterialRequisiteForm mrForm = service.getMaterialRequisiteForm(getFormId());
		Set<MaterialRequisiteFormDetail> formDetails = mrForm.getFormDetails();
		int index = 0;
		for (MaterialRequisiteFormDetail detail : formDetails) {
			detail.setNumber(materialNums.get(index));
			index++;
		}
		backService.saveBackMaterialRequisiteForm(mrForm);
		return SUCCESS;
	}
	
	private boolean hasBackNum(List<Float> numbers) {
		for (float number : numbers) {
			if (number > 0) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 保存退料单
	 * @return
	 * @throws Exception
	 */
	public String saveBackMaterialRequisiteForm() throws Exception {
		List<Integer> materialIds = getMaterialIds();
		MaterialRequisiteForm mrForm = service.getMaterialRequisiteForm(getFormId());
		Set<MaterialRequisiteFormDetail> formDetails = mrForm.getFormDetails();
		MaterialRequisiteForm qualifiedBackForm = null;
		if (hasBackNum(qualifiedBackNums)) {
			qualifiedBackForm = mrForm.copy();
			qualifiedBackForm.setSourceFormId(mrForm.getId());
			qualifiedBackForm.getFormDetails().clear();
			float number = 0;
			int count = qualifiedBackNums.size();
			for (int i = 0; i < count; i++) {
				number = qualifiedBackNums.get(i);
				if (number > 0) {
					int materialId = materialIds.get(i);
					MaterialRequisiteFormDetail detail = findMaterial(materialId, formDetails);
					if (detail != null) {
						detail = detail.copy();
						detail.setRealNumber(0);
						detail.setBackNumber(0);
						detail.setNumber(number);
						qualifiedBackForm.addDetail(detail);
					}
				}
			}
		}

		MaterialRequisiteForm unqualifiedBackForm = null;
		if (hasBackNum(unqualifiedBackNums)) {
			unqualifiedBackForm = mrForm.copy();
			unqualifiedBackForm.setSourceFormId(mrForm.getId());
			unqualifiedBackForm.getFormDetails().clear();
			float number = 0;
			int count = unqualifiedBackNums.size();
			for (int i = 0; i < count; i++) {
				number = unqualifiedBackNums.get(i);
				if (number > 0) {
					int materialId = materialIds.get(i);
					MaterialRequisiteFormDetail detail = findMaterial(materialId, formDetails);
					if (detail != null) {
						detail = detail.copy();
						detail.setRealNumber(0);
						detail.setBackNumber(0);
						detail.setNumber(number);
						unqualifiedBackForm.addDetail(detail);
					}
				}
			}
		}
		backService.saveBackMaterialRequisiteForm(qualifiedBackForm, unqualifiedBackForm);
		return SUCCESS;
	}
	
	private MaterialRequisiteFormDetail findMaterial(int materialId, Set<MaterialRequisiteFormDetail> formDetails) {
		for (MaterialRequisiteFormDetail detail : formDetails) {
			if (detail.getMaterialId() == materialId) {
				return detail;
			}
		}
		return null;
	}
/*
	public String getFormId() {
		return formId;
	}

	public void setFormId(String formId) {
		this.formId = formId;
	}

	public List<Integer> getMaterialIds() {
		return materialIds;
	}

	public void setMaterialIds(List<Integer> materialIds) {
		this.materialIds = materialIds;
	}
*/
	public List<Float> getQualifiedBackNums() {
		return qualifiedBackNums;
	}

	public void setQualifiedBackNums(List<Float> qualifiedBackNums) {
		this.qualifiedBackNums = qualifiedBackNums;
	}

	public List<Float> getUnqualifiedBackNums() {
		return unqualifiedBackNums;
	}

	public void setUnqualifiedBackNums(List<Float> unqualifiedBackNums) {
		this.unqualifiedBackNums = unqualifiedBackNums;
	}
/*
	public List<Integer> getMaterialNums() {
		return materialNums;
	}

	public void setMaterialNums(List<Integer> materialNums) {
		this.materialNums = materialNums;
	}

	public void setMrForm(MaterialRequisiteForm mrForm) {
		this.mrForm = mrForm;
	}

	public MaterialRequisiteForm getMrForm() {
		return mrForm;
	}

	public List<Integer> getDetailIds() {
		return detailIds;
	}

	public void setDetailIds(List<Integer> detailIds) {
		this.detailIds = detailIds;
	}
*/
	public List<Float> getInStroeNumbers() {
		return inStroeNumbers;
	}

	public void setInStroeNumbers(List<Float> inStroeNumbers) {
		this.inStroeNumbers = inStroeNumbers;
	}

	public List<String> getInStroeBatchNos() {
		return inStroeBatchNos;
	}

	public void setInStroeBatchNos(List<String> inStroeBatchNos) {
		this.inStroeBatchNos = inStroeBatchNos;
	}

	public void setCheckResult(OrderCheck checkResult) {
		this.checkResult = checkResult;
	}

	public OrderCheck getCheckResult() {
		return checkResult;
	}

	public void setCheckResults(List<OrderCheck> checkResults) {
		this.checkResults = checkResults;
	}

	public List<OrderCheck> getCheckResults() {
		return checkResults;
	}
	
	
}
